<?php

class PageUrlService extends FServiceBase
{    
    /**
    * Get a PageUrl model given its ID
    * 
    * @param int id PageUrl ID
    * @return FServiceModel
    */
    public function get($params){
        $model = PageUrl::model()->findByPk($this->getParam($params, 'id',0));
        if (! $model)
            $this->result->fail(ERROR_INVALID_DATA, Yii::t('Cms.PageUrl','Invalid ID.'));
        $this->result->processed('model', $model);
        return $this->result;
    }
    
    public function save($params) {
        /**
        * @var CModel
        */
        $model = $this->getModel($params['PageUrl'],'PageUrl','notag,xss,newline');
        $this->result->processed('model', $model);
        
        $model->setScenario('new');
        if (! $model->validate())
            $this->result->fail(ERROR_INVALID_DATA, Yii::t('Cms.PageUrl', 'Submitted data is missing or invalid.'));
        elseif ($this->getParam($params, 'validateOnly',0) == TRUE)
            return $this->result;
        elseif (! $model->save(false))
            $this->result->fail(ERROR_HANDLING_DB, Yii::t('Cms.PageUrl','Error while saving submitted data into database.'));
        elseif ($model->status && $model->default)
            $this->setDefault(array('page_id'=>$model->page_id, 'id'=>$model->id));
        
        FSM::_run('Cms.pageUrl.updateCacheUrlBySite',array('site_id' => $model->page->site_id));
        
        return $this->result;
    }


    public function delete($params) {
        $ids = $this->getParam($params, 'ids', array());
        if ($ids == 0) {
            return $this->result->fail(ERROR_INVALID_DATA, Yii::t('Cms.PageUrl','Invalid ID.'));
        }
      
        if (!is_array($ids)) $ids = array($ids);
        foreach($ids as $id) {
            $model = PageUrl::model()->findByPk($id);
            /**
            * TODO: Check related data if this PageUrl is deletable
            * This can be done in onBeforeDelete or here or in extensions
            *
            if (Related::model()->count("PageUrlId = {$id}") > 0)
                $this->result->fail(ERROR_VIOLATING_BUSINESS_RULES, Yii::t('Cms.PageUrl',"Cannot delete PageUrl ID={$id} as it has related class data."));
            else
            */
                try {
                    $model->delete();
                } catch (CDbException $ex) {
                    $this->result->fail(ERROR_HANDLING_DB, $ex->getMessage());
                }
        }
        return $this->result;
    }

    public function deleteAllByPageId($params) {
        $pageId = $this->getParam($params, 'page_id', 0);
        if (!$pageId)
            return $this->result->fail(ERROR_INVALID_DATA, Yii::t('Cms.PageRevision','Invalid ID.'.CVarDumper::dumpAsString($pageId)));
      
        PageUrl::model()->deleteAllByAttributes(array('page_id'=>$pageId));

        return $this->result;
    }
    
    public function changeStatus($params) {
        $ids = $this->getParam($params, 'ids', array());
        $value = $this->getParam($params, 'value', false);
        
        if (count($ids) <= 0)
            return $this->result;
        
        $criteria = new CDbCriteria();
        $criteria->addInCondition('id', $ids);
        $models = PageUrl::model()->findAll($criteria);
        foreach ($models as $model) {
            /**
            * @var Site $model
            */
            $model->status = (boolean) $value;
            if (! $model->save(false, array('status')))
                $this->result->fail(ERROR_HANDLING_DB, Yii::t('CmsModule.Site','Error while saving submitted data into database.'));
        }
        
        return $this->result;
    }
    
    public function setDefault($params)
    {
        $id = $this->getParam($params, 'id', 0);
        $pageId = $this->getParam($params, 'page_id', 0);
        if ($id) {
            $model = PageUrl::model()->findByPk($id);
            if (is_object($model) && $model->status) {
                PageUrl::model()->updateAll(array('default'=>false), 'page_id=:page_id', array(':page_id'=>$pageId));
                PageUrl::model()->updateByPk($id, array('default'=>true), 'page_id=:page_id', array(':page_id'=>$pageId));
            }
        }
        return $this->result;
    }
    
    public function getDefaultUrlByPage($params)
    {
    	$pageId = $this->getParam($params, 'pageId', 0);
		$defaultUrl = PageUrl::model()->find("page_id = {$pageId} AND default = 1");
		$this->result->processed('model', $defaultUrl);
		return $this->result; 
    }
    
    /**
    * Build cache file of page urls in a given workflow
    * 
    * @param string workflowUrl 
    */
    public function cacheUrls($params)
    {
        $workflowUrl = $this->getParam($params, 'workflowUrl','');
        $workflow = Workflow::model()->find('url = :url', array(':url' => $workflowUrl));
        
        if (!is_object($workflow))
            return $this->result->fail(ERROR_INVALID_DATA, Yii::t('CmsModule.PageUrl','Found no workflow with specified url'));
        
        $criteria = new CDbCriteria();
        $criteria->order = 'url asc';
        
        $pageUrls = PageUrl::model()->with(
                array(
                    'page'=>array(
                        'select'=>'id,type,route',
                        'condition'=>'page.site_id=:site_id',
                        'params'=>array(':site_id'=>$workflow->site_id),
                    )
                )
            )->findAll($criteria);
        $urls = array();
        if (count($pageUrls))
        {
            foreach($pageUrls as $url) {
                // tranlsate parameter marker from user friendly ([]) to Yii standar (<>)
                $url->url = strtr($url->url,'[]','<>');
                if ($url->page->type === Page::TYPE_STANDARD)
                {
                    $urls[] = array($url->page->route, $url->url);
                }
                else
                {
                    $urls[] = $url->url;
                }
            }
        }
        
        file_put_contents(cachePath().'/'.str_replace('/','.',$workflowUrl).'.php',str_replace('\\\\','\\',var_export($urls,true)));
        return $this->result;
    }
    
    /**
    * Get cached page urls of a given workflow
    * 
    * @param string workflowUrl 
    */
    public function getCachedUrls($params)
    {
        $workflowUrl = $this->getParam($params, 'workflowUrl','');
        
        $file = cachePath().'/'.str_replace('/','.',$workflowUrl).'.php';
        
        if (!file_exists($file)) {
            //TODO: check if cache is expired and in that case rebuild it
            $result = $this->cacheUrls($params);
            if ($result->hasErrors()) 
                return $this->result->fail(ERROR_INVALID_DATA,Yii::t('CmsModule.PageUrl','Tried to load cached urls of an invalid workflow.'));
        }
        
        if (($cacheStr = file_get_contents($file)) == '')
            $urls = array();
        else
            eval('$urls = '.file_get_contents($file).';');
        
        $this->result->processed('urls',$urls);
        return $this->result;
    }
    
    public function updateCacheUrlBySite($params)
    {
        $siteId = $this->getParam($params, 'site_id', 0);
        $result = FSM::_run('Cms.Workflow.getBySite', array('site_id'=>$siteId));
        if (!$result->hasErrors())
        {
            $models = $result->models;
            if (is_array($models) && count($models))
            {
                foreach ($models as $model)
                {
                    FSM::_run('Cms.PageUrl.cacheUrls',array('workflowUrl' => $model->url));
                }
            }
        }
        return $this->result;
    }
    
    /**
    * copy page url from site to site
    * 
    * @param array $params
    * <ul>
    *   <li>source_page_id: int, required, copy from source page_id</li>
    *   <li>target_page_id: int, required, copy to target page_id</li>
    * </ul>
    * 
    * @return FServiceModel
    */
    public function copy($params)
    {
        $sourcePageId = $this->getParam($params, 'source_page_id', 0);
        $targetPageId = $this->getParam($params, 'target_page_id', 0);
        
        $models = array();
        if ($sourcePageId && $targetPageId)
        {
            $criteria = new CDbCriteria();
            $criteria->compare('page_id', $sourcePageId);
            $items = PageUrl::model()->findAll($criteria);
            if (count($items))
            {
                foreach ($items as $model)
                {
                    $criteria = new CDbCriteria();
                    $criteria->compare('page_id', $targetPageId);
                    $criteria->compare('url', $model->url);
                    if (!PageUrl::model()->exists($criteria))
                    {
                        /**
                        * @var PageUrl
                        */
                        $model->setIsNewRecord(true);
                        $model->id = null;
                        $model->page_id = $targetPageId;
                        if ($model->save())
                        {
                            array_push($models, $model);
                        }
                        else
                        {
                            Yii::log(CVarDumper::dumpAsString($model->getErrors()), CLogger::LEVEL_ERROR);
                        }
                    }
                }
            }
        }
        else
            $this->result->fail(ERROR_INVALID_DATA, Yii::t('CmsModule.Page', 'Submitted data is missing or invalid.'));
            
        $this->result->processed('models', $models);
        
        return $this->result;
    }
}